using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using DevExpress.XtraGrid.Views.Grid.ViewInfo;
using DevExpress.Data.Filtering;
using ChuanPlus.DAO;
namespace ChuanPlus.FormControl
{
    public partial class ControlNewSample : DevExpress.XtraEditors.XtraUserControl
    {
        List<SampleProduct> lstSampleProduct = new List<SampleProduct>();
        public ControlNewSample()
        {
            InitializeComponent();
            xpColStock.Criteria = CriteriaOperator.Parse("warehouseID.warehouseId = 1");
            comboApprovedBy.Properties.Items.AddRange(xpUsers);
            comboTakeBy.Properties.Items.AddRange(xpUsers);
            comboCustomer.Properties.Items.AddRange(xpColCustomer);
            gridRight.DataSource = lstSampleProduct;
            dateTaken.DateTime = DateTime.Today;
        }

        

        private void gridView2_DoubleClick(object sender, EventArgs e)
        {
            // Checks whether an end-used has double clicked the row indicator.
            GridHitInfo hi = gridView2.CalcHitInfo(gridLeft.PointToClient(MousePosition));
            if (!hi.InRow) return;
            // Retrieves the persistent object that corresponds to the currently focused grid row.
            int DSRowIndex = gridView2.Columns.View.GetDataSourceRowIndex(gridView2.FocusedRowHandle);
            Stock currentStock = xpColStock[DSRowIndex] as Stock;
            if (currentStock.warehouseID.warehouseId == 2)  // do not get sample from stock, just get from office
                return;
            SampleProduct p = new SampleProduct(currentStock, currentStock.ID.ItemCode, currentStock.ID.Description, 0);
            if (lstSampleProduct.Contains(p))     // do not add to list if product is added
                return;

            lstSampleProduct.Add(p);
            gridRight.RefreshDataSource();
        }

        private void textFilter_EditValueChanged(object sender, EventArgs e)
        {
            CriteriaOperator opeLeft = new BinaryOperator(new OperandProperty("ID.ItemCode"), new OperandValue("%" + textFilter.Text + "%"), BinaryOperatorType.Like);
            CriteriaOperator opeRight = new BinaryOperator(new OperandProperty("ID.Description"), new OperandValue("%" + textFilter.Text + "%"), BinaryOperatorType.Like);
            CriteriaOperator filter = new GroupOperator(GroupOperatorType.Or, new CriteriaOperator[2] { opeLeft, opeRight });
            xpColStock.Filter = filter;

        }

        
        #region validation

        private bool FormValidation()
        {
            if (comboCustomer.SelectedItem == null)
            {
                MessageBox.Show("Please select one customer", "Message");
                comboCustomer.Focus();
                return false;
            }
            if (dateTaken.Text == "")
            {
                MessageBox.Show("Please select take date", "Message");
                dateTaken.Focus();
                return false;
            }
            if (comboTakeBy.SelectedItem == null)
            {
                MessageBox.Show("Please select take sample employee", "Message");
                comboTakeBy.Focus();
                return false;
            }
            if (comboApprovedBy.SelectedItem == null)
            {
                MessageBox.Show("Please select approver", "Message");
                comboApprovedBy.Focus();
                return false;
            }
            if (lstSampleProduct.Count == 0)
            {
                MessageBox.Show("Please select sample product", "Message");
                return false;
            }
            int DSIndex = validateQuantity();
            if (DSIndex != -1)
            {
                gridView1.FocusedRowHandle = gridView1.GetRowHandle(DSIndex);
                return false;
            }
            return true;
        }
        
        private void comboCustomer_Validating(object sender, CancelEventArgs e)
        {
            Customer c = comboCustomer.SelectedItem as Customer;
            if (c == null)
            {
                e.Cancel = true;
                comboCustomer.ErrorText = "Customer " + comboCustomer.Text + " does not exsit";
            }
        }

        private void comboTakeBy_Validating(object sender, CancelEventArgs e)
        {
            Users u = comboTakeBy.SelectedItem as Users;
            if (u == null)
            {
                e.Cancel = true;
                comboTakeBy.ErrorText = "Staff " + comboTakeBy.Text + " does not exsit";
            }
        }

        private void comboApprovedBy_Validating(object sender, CancelEventArgs e)
        {
            Users u = comboApprovedBy.SelectedItem as Users;
            if (u == null)
            {
                e.Cancel = true;
                comboApprovedBy.ErrorText = "Staff " + comboApprovedBy.Text + " does not exsit";
            }
        }
        private void gridView1_ValidatingEditor(object sender, DevExpress.XtraEditors.Controls.BaseContainerValidateEditorEventArgs e)
        {
            if (gridView1.FocusedColumn.FieldName == "Quantity")
            {
                int DSRowIndex = gridView1.Columns.View.GetDataSourceRowIndex(gridView1.FocusedRowHandle);
                double instock = lstSampleProduct[DSRowIndex].stock.QtyBalance;
                //Get the currently edited value
                double qty = Convert.ToDouble(e.Value);
                //Specify validation criteria
                if (qty < 0)
                {
                    e.Valid = false;
                    e.ErrorText = "Enter a positive value";
                }
                if (qty > instock)
                {
                    e.Valid = false;
                    e.ErrorText = "Reduce the quantity (" + instock + " is maximum)";
                };
            }
        }
        private int validateQuantity()
        {
            for (int i = 0; i < lstSampleProduct.Count; i++)
            {
                if (lstSampleProduct[i].Quantity <= 0)
                {
                    MessageBox.Show("Please enter sample quantity","Message",MessageBoxButtons.OK,MessageBoxIcon.Error);
                    return i;
                }
            }
            return -1;
        }
        #endregion
        private void ButtonSubmit_Click(object sender, EventArgs e)
        {
            if (!FormValidation()) return;
            Sample sample = new Sample(comboTakeBy.SelectedItem as Users,comboCustomer.SelectedItem as Customer,comboApprovedBy.SelectedItem as Users,dateTaken.DateTime,"H");
            foreach (SampleProduct item in lstSampleProduct)
            {
                SampleDetails detail = new SampleDetails(item.stock, item.Quantity);
                sample.SampleDetails.Add(detail);
            }
            sample.Save();            
            lstSampleProduct.Clear();
            gridRight.RefreshDataSource();
            reset();
        }

        private void gridView1_KeyDown(object sender, KeyEventArgs e)
        {
            if(e.KeyCode == Keys.Delete && gridView1.FocusedRowHandle >= 0)
            {
                // Retrieves the persistent object that corresponds to the currently focused grid row.
                int DSRowIndex = gridView1.Columns.View.GetDataSourceRowIndex(gridView1.FocusedRowHandle);
                lstSampleProduct.RemoveAt(DSRowIndex);     // do not add to list if product is added      
                gridRight.RefreshDataSource();
            }
        }
        private void reset()
        {
            comboCustomer.SelectedItem = null;
            comboTakeBy.SelectedItem = null;
            comboApprovedBy.SelectedItem = null;
        }
    }
    public class SampleProduct
    {
        private Stock _Stock;
        public Stock stock
        {
            get { return _Stock; }
            set { _Stock = value; }
        }
        private string _ItemCode;
        public string ItemCode
        {
            get { return _ItemCode; }
            set { _ItemCode = value; }
        }
        private string _Description;
        public string Description
        {
            get { return _Description; }
            set { _Description = value; }
        }
        private double _Quantity;
        public double Quantity
        {
            get { return _Quantity; }
            set { _Quantity = value; }
        }
        public override bool Equals(Object b)
        {
            bool result = true;
            if (b == null) result = false;
            try
            {
                SampleProduct p = (SampleProduct)b;
                if (p.stock.ID == this.stock.ID)
                    result = true;
                else
                    result = false;
            }
            catch
            {
                result = false;
            }
            return result;
        }
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
        /// <summary>
        /// Initializes a new instance of the SampleProduct class.
        /// </summary>
        /// <param name="product"></param>
        /// <param name="itemCode"></param>
        /// <param name="description"></param>
        /// <param name="quantity"></param>
        public SampleProduct(Stock stock, string itemCode, string description, double quantity)
        {
            _Stock = stock;
            _ItemCode = itemCode;
            _Description = description;
            _Quantity = quantity;
        }
    }
}
